• log ana
  • 排错
  • 注意 note
  • log reader config
  • log ana design
  • config
  • log ana 日志
  • check list
  • log ana 部署
  • 部署步骤
  • commits
  • ana.php 一次性分析处理所有日志
  • ana 优化 fgets
  • mynote seaslog 日志解析
  • 将上次的读取位置保存到mysql数据库中:
  • mynote_log 加入logger字段
  • logger时间精确到毫秒
  • 实时分析 位置缓存
  • mynote_login uid + sessionid 重复问题
  • 关联sessionid和用户
  • 临时表去重,可能存在性能问题
  • 测试点
  • dev tools
  • test cases
  • mynote request log
  • mynote log 混合编码
  • 支持 date/delta 参数,date 优先,-- 隔天丢失问题
  • nginx 访问日志处理
  • seo sql
  • 开源 IP 地址定位库 ip2region 1.9.0 发布
  • IPIP.net - 实际使用
  • lv1= lv2= type=
    log ana
    log ana todo 
    http://a.add.my/log_storage
    〖E:\uninote\additional_item\log_storage\bin\Analysis〗
    obsolete:
    http://a.myres.my/log.viewer/
    〖E:\uninote\mynote_res\logviewer〗
    〖E:\uninote\mynote_res\log_analysis〗
    exception分析工具,相同的堆栈,md5作为标示
    nginx log分析 耗时记录
    定时器分析:??
    E:\uninote\mynote\art_workman\start.php
    E:\uninote\mynote\art_workman\Application\Mlog.php
    分为两部分,解析存储 + 读取

    排错

    mynote_indexfile 清理,重新分析

    注意 note

    注意:编码、linefeed
    目前只有mynote_log的分析有多行的问题,其他的日志都是单行记录。
    message 过长 - 删除日志 临时解决 -- try/catch
    lv1= lv2= type=

    log reader config

    已经内联分析,查询时即执行 ana。
    ---------- local:
    <?php
    $g_config["pwd"] = "root";
    /*日志解析路径*/
    $g_config['item'] = [
        [
            "api" => "mynote_log", //模块名称
            "path" => "E:/uninote/mynote/basic/runtime/seaslog/default" //实际情况日志路径
        ],
        [
            "api" => "mynote_login",
            "path" => "E:/uninote/mynote/basic/runtime/seaslog/login"
        ],
        [
            "api" => "mynote_request",
            "path" => "E:/uninote/mynote/basic/runtime/logs/logs.txt"
        ]
    ];
    ---------- online:
    <?php
    $g_config["pwd"] = "root123.";
    /*日志解析路径*/
    $g_config['item'] = [
        [
            "api" => "mynote_log", //模块名称
            "path" => "/home/www/mynote/basic/runtime/seaslog/default" //实际情况日志路径
        ],
        [
            "api" => "mynote_login",
            "path" => "/home/www/mynote/basic/runtime/seaslog/login"
        ],
        [
            "api" => "mynote_request",
            "path" => "/home/www/mynote/basic/runtime/logs/logs.txt"
        ]
    ];
    lv1= lv2= type=

    log ana design

    记录、分析、查看
    user mynote_login mynote_request mynote_log
    筛选(filter):按人、时间
    request.id 显示在头部(红色),log.id 显示在每条日志中(绿色区域)
    日志内容显示在蓝色区域
    post参数显示在黄色区域,可以直接复制到api/tests,进行调试
    过滤条件(每张表可能都有过滤字段):
    uid, 手机号、reqnum、时间段
    message like
    uri
    请求消耗时间 > 200ms
    要点:
    查询的主要脉络应该是request表,但request可能不和任何user、login(无登录记录)、log(此request无任何日志输出)表关联
    查询结果排序:
    按request id排序,则无法按照日志发生的先后顺序显示;
    按log id排序,因为有的request无log,因此此类request显示有问题。
    解决方案:
    lv1= lv2= type=todo
    cyb:使用日志时间排序
    IFNULL(log.datetime,r.datetime) AS 记录时间,
    lv1= lv2= type=

    config

    同 reader config
    log reader config 
    lv1= lv2= type=

    log ana 日志

    E:\uninote\additional_item\log_storage\bin\Analysis\Analysis.php
    E:\uninote\additional_item\log_storage\logs\log.txt

    check list

    SHA-1: 4312417640264ac9086b466fccd2571eb85c5ca9
    * bug fix:添加common.php 的引用
    lv1= lv2= type=

    log ana 部署

    log reader config 
    nginx config: E:\back\git\mynote\online\nginx\vhost\additional_item_82.conf
    sql/*.sql 初始化

    部署步骤

    - 在php.ini中配置seaslog的输出模板:
    seaslog.default_template = "%t -||- %L -||- %R -||- %C -||- %F -||- %Q -||- %M"
    - 在mynote数据库中执行所有子目录下的create.sql,生成对应的日志表。
    - 执行一次登录,并随意浏览网站
    - 运行http://a.add.my/log_storage/ana.php,手动将生成的日志解析并存储到数据库中
    或者直接访问 http://a.add.my/log_storage/,会自动分析

    commits

    tbname & logpath 可以从url中覆盖
    ed83711eca2a13c16db4d3a38a26983a397c7747
    eg:
    http://a.add.my/log_analysis/mynote_request/process.php?logpath=logs.txt&tbname=abc
    注意,必要时参数需要urlEncode
    SHA-1: d04f40f687b150a79162145a5b6b196eaa31c5e3
    * 【更新】- 日志采集功能更新,更改文件记录末尾行数存储mysql避免行号不对的错误
    lv1= lv2= type=

    ana.php 一次性分析处理所有日志

    直接 http 访问:
    http://a.add.my/log_storage/ana.php
    结果见日志
    config 
    也可以在访问 GUI 时触发
    lv1= lv2= type=

    ana 优化 fgets

    这个有性能问题:
    $lines = explode("\n", $content);
    $countLines = count($lines);
    lv1= lv2= type=

    mynote seaslog 日志解析

    文件夹:mynote_log
    数据库表结构:
    datetime level uri class filename reqid message
    其中,需要将level字段翻译为level数字,参见SeasLog 共将日志分成8个级别 
    seaslog配置:
    seaslog.default_template = "%t  %L  %R  %C  %F  %Q  %M"
    seaslog.default_logger=default
    seaslog.disting_folder = 1
    seaslog.disting_type=0
    seaslog.disting_by_hour=0
    seaslog.use_buffer=1
    seaslog.buffer_size=100
    seaslog.level=8
    seaslog.trace_error=1
    seaslog.trace_exception=0
    优化:
    放到开头,作为一条log的标记。
    fgets,不要一次性读取所有文件。
    %R 不用了
    lv1=mynote lv2= type=done
    不要存成一行,显示时需要换行
     [cmd]: git commit -m 'update' 2>&1[update_0137822208 63a2a1e] 'update' 2 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 1535965471
    white-space: pre-line;
    lv1=mynote lv2= type=done

    将上次的读取位置保存到mysql数据库中:

    log_analysis/common.php
    $indexfile_path = "./last_end_index.txt";
    if (!file_exists($indexfile_path)) {
        file_put_contents($indexfile_path, 0);
    }
    lv1=mynote lv2= type=done

    mynote_log 加入logger字段

    用于保存logger
    lv1=mynote lv2= type=done

    logger时间精确到毫秒

    时间使用%t,修改解析处:
    "%t -||- %L -||- %C -||- %F -||- %Q -||- %M"

    实时分析 位置缓存

    为了支持实时分析,在mynote_indexfile表中记录上次分析到的位置(文件偏移量)
    注意大小写问题
    lv1= lv2= type=

    mynote_login uid + sessionid 重复问题

    lv1=mynote lv2= type=done
    reqnum用get_time?重复太多
    log sessionid重复查询:
    select count(*) as cnt, login.sessionid 
    from mynote_login login
    GROUP BY login.sessionid
    HAVING cnt >1
    特定id查看:
    SELECT * FROM `mynote_login` WHERE sessionid = 'k18v46c4k11m7tjs5vhndc0ktv'
    mynote_request 记录请求时间
    reqnum 重复查询:
    SELECT count(*) as cnt, r.reqnum, r.sessionid
    from mynote_request r
    GROUP BY r.reqnum
    having cnt > 1
    select *from mynote_request where reqnum = 6951333

    关联sessionid和用户

    在用户登录时记录到logger login:E:\uninote\mynote\basic\runtime\seaslog\login
    但用户退出登录后,下次再登录,sessionid并不会改变。此时一条log就会对应两个登录记录(用户),查询时就是一条log显示两次。
    解决办法:注销后前端清除sessionid
    * 注销后删除cookie,方便日志分析 
    但这种方法并不一定有效,比如:服务器上session过期,此时重新登录,还是会存在同一个sessionid两次登录的情况
    终极办法:* opt: 避免登录时复用 cookie,保证每个 session 使用的 cookie 都是唯一的 
    但这样会丢掉登录前的操作日志
    用uid+sid做判定,如果仍然是上次用户,忽略此次 login 记录;否则重新分配 sid
    或者合并可能的多用户

    临时表去重,可能存在性能问题

    * feat: mynote_login 通过临时表去重
    -            LEFT JOIN mynote_login AS login ON
    +            LEFT JOIN (SELECT uid, sessionid from mynote_login GROUP BY uid, sessionid) AS login ON

    测试点

    图片接口

    dev tools

    TRUNCATE table mynote_log;
    truncate table mynote_request;
    update mynote_indexfile set last_end_index = 0 where indexfile_path = 'E:/uninote/mynote/basic/runtime/seaslog/default/20190930.log';
    select * from mynote_indexfile where indexfile_path = 'E:/mynote/basic/runtime/seaslog/default/20190422.log';
    SELECT * from mynote_log;

    test cases

    empty
    one line
    one line + oneline
    mline + mline
    oneline + mline
    mline + online
    lv1= lv2= type=

    mynote request log

    SHA-1: f69244347bd8a3cbad51a5cd5a988ccec973c11d
    * 用 finally 保证每个请求的 log 完整(REQUEST_END 的记录)
    php error reporting/handling exception 异常、错误处理 
    finally {
        /* CT log end */
        CT_log("--REQUEST_END:" . $g_REQUEST_URI . "|| PHPSESSID: " . $g_PHPSESSID . "|| rnum: " . $request_num .
            "|| time: " . (get_time() - $g_begintime) . "s");
        CT_flush(true);
    }
    lv1= lv2= type=

    mynote log 混合编码

    windows 下 yii redis 抛出的错是 gbk 编码的,其他都是utf8:
    [error][yii\redis\Connection] Failed to open redis DB connection (localhost:6379, database=0): 10061 - 由于目标计算机积极拒绝,无法连接。
    lv1= lv2= type=

    支持 date/delta 参数,date 优先,-- 隔天丢失问题

    分析前一天的:
    http://uninote.com.cn:82/log_storage/ana.php?delta=1
    分析指定日期:
    http://uninote.com.cn:82/log_storage/ana.php?date=20210706
    lv1= lv2= type=

    nginx 访问日志处理

    已经暂定copy,没法使用 ln -s
    docker cp /usr/local/nginx/logs/ut-online.access.log mynote-online:/home/www/mynote/basic/runtime/logs/nginx.log
    # vi /etc/crontab
    * * * * * root docker cp /usr/local/nginx/logs/ut-online.access.log mynote-online:/home/www/mynote/basic/runtime/logs/nginx.log >> /tmp/docker-cp.log 2>&1
    然后访问:http://uninote.com.cn:82/log_storage/ana.php
    查看日志:
    tail -f /home/www/additional_item/log_storage/logs/log.txt
        [
            "api" => "xjc_nignx",
            "path" => "/home/www/mynote/basic/runtime/logs/nginx.log"
        ],
        [
            "api" => "xjc_nignx",
            "path" => "/home/www/mynote/basic/runtime/logs/nginx-old.log"
        ]

    seo sql

    SELECT u.nick , n.* from xjc_nginx n
    LEFT JOIN mynote_login l on n.sessid = l.sessionid
    LEFT JOIN `user` u on l.uid = u.id
    where time > '2020-07-06' 
    -- and ua like '%google%' 
    and referer like '%www.google%'
    and request like '%/book/%'
    -- and request like '%/book/%'
    SELECT* from xjc_nginx where time > '2021-07-06 22' 
    SELECT* from xjc_nginx where 
    time > '2021-07-06 22' 
    and ua like '%mobile%'
    select * from xjc_nginx WHERE sessid = '4icdu9f6mns97pvueftfqpmtd0'
    and request like '%login%'
    SELECT* from xjc_nginx where ip = '180.169.253.136'
    and request like '%/book/%'
    SELECT* from xjc_nginx where time > '2020-07-06' 
    -- and ua like '%google%' 
    and referer like '%www.baidu.com%'
    SELECT uid, sessionid from mynote_login
    GROUP BY uid, sessionid
    desc mynote_login
    SELECT DISTINCT uid, sessionid from mynote_login
    where uid = 1039 and sessionid='001bkbvhrbjghl0h0hl4kut0u7'

    开源 IP 地址定位库 ip2region 1.9.0 发布

    https://cloud.tencent.com/developer/article/1578818?from=information.detail.php%E6%9C%80%E6%96%B0ip%E5%9C%B0%E5%9D%80%E5%BA%93

    IPIP.net - 实际使用

    unicyber
    2848
    7857
    https://www.ipip.net/product/client.html
    https://github.com/ipipdotnet/ipdb-php
    feat: ip 反解城市